package hu.lacimol.tutorial.todo.scheduling;

import hu.lacimol.tutorial.todo.service.TodoService;
import hu.lacimol.tutorial.todo.util.GlobalSettings;

import java.util.Date;
import java.util.HashMap;

import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.atlassian.sal.api.lifecycle.LifecycleAware;
import com.atlassian.sal.api.pluginsettings.PluginSettingsFactory;
import com.atlassian.sal.api.scheduling.PluginScheduler;

public class TodoMonitorImpl implements TodoMonitor, LifecycleAware {
	
	private static final Logger logger = LoggerFactory.getLogger(TodoMonitorImpl.class);
	private static final String JOB_NAME = TodoMonitorImpl.class.getName() + ":job";
	
	private final PluginScheduler pluginScheduler;
	private final TodoService todoService;
	private final GlobalSettings settings;
	
	private final HashMap<String, Object> jobDataMap = new HashMap<String, Object>();
	
	private Date lastRun;
	private Date nextRun;
	private long interval = 0;
	
	public TodoMonitorImpl(PluginScheduler pluginScheduler, TodoService todoService,
			PluginSettingsFactory pluginSettingsFactory) {
		
		this.pluginScheduler = pluginScheduler;
		this.todoService = todoService;
		this.settings = new GlobalSettings(pluginSettingsFactory.createGlobalSettings());
		
		Long loadInterval = this.settings.loadInterval();
		if (loadInterval != null) {
			this.interval = loadInterval;
		}
		
	}
	
	@Override
	public void onStart() {
		
		this.jobDataMap.put("TodoMonitorImpl:instance", TodoMonitorImpl.this);
		this.jobDataMap.put("TodoService", this.todoService);
		
		if (this.interval > 0) {
			schedule();
		}
	}
	
	@Override
	public void reschedule(long interval) {
		this.interval = interval;
		this.settings.storeInterval(interval);
		this.schedule();
	}
	
	private void schedule() {
		DateTime startTime = this.lastRun == null ? DateTime.now() : new DateTime(this.lastRun);
		this.pluginScheduler.scheduleJob(JOB_NAME, TodoTask.class, this.jobDataMap, startTime.toDate(), this.interval);
		this.setNextRun(startTime.plus(this.interval).toDate());
		logger.info(String.format("TodoMonitorImpl scheduled to run every %d ms", this.interval));
	}
	
	@Override
	public void setLastRun(Date lastRun) {
		this.lastRun = lastRun;
	}
	
	@Override
	public Date getLastRun() {
		return this.lastRun;
	}
	
	@Override
	public Date getNextRun() {
		return this.nextRun;
	}
	
	@Override
	public void setNextRun(Date nextRun) {
		this.nextRun = nextRun;
	}
	
	@Override
	public long getInterval() {
		return this.interval;
	}
	
	@Override
	public int getTodoSize() {
		return this.todoService.findAll().size();
	}
	
}